package cn.com.surker.material.service.impl;

import cn.com.surker.base.BaseEntity;
import cn.com.surker.common.MessageCenterException;
import cn.com.surker.database.JDBCTemplateCache;
import cn.com.surker.dto.main.MainMaterialBillAddDTO;
import cn.com.surker.dto.main.MainMaterialBillAuditDTO;
import cn.com.surker.dto.main.MainMaterialBillDTO;
import cn.com.surker.enums.material.MaterialBreedTypeEnum;
import cn.com.surker.enums.material.MaterialContractTypeEnum;
import cn.com.surker.enums.material.SysMaterialTypeEnum;
import cn.com.surker.enums.system.BillEnum;
import cn.com.surker.enums.system.BillPriceTypeEnum;
import cn.com.surker.enums.system.CheckEnum;
import cn.com.surker.enums.system.DataBaseEnum;
import cn.com.surker.material.dao.*;
import cn.com.surker.material.entity.MainMaterial;
import cn.com.surker.material.entity.MainMaterialBill;
import cn.com.surker.material.entity.MainMaterialContractPrice;
import cn.com.surker.material.service.MaterialBillBaseService;
import cn.com.surker.material.vo.MainMaterialBillVo;
import cn.com.surker.material.vo.MainMaterialWeightVo;
import cn.com.surker.material.vo.MaterialTransportPriceVo;
import cn.com.surker.oa.dao.OaSupplierDao;
import cn.com.surker.oa.entity.OaSupplier;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.DataSourceInfoDao;
import cn.com.surker.system.dao.SysOriginDao;
import cn.com.surker.system.dao.SysReportTimeDao;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.system.entity.SysOrigin;
import cn.com.surker.system.entity.SysReportTime;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import cn.com.surker.vo.main.MainMaterialBillVO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
* <p>
    * 主材材料结算信息表 服务实现类
    * </p>
*
* @author admin
* @since 2024-12-03
*/
public abstract class MaterialBillBaseServiceImpl extends ServiceImpl<MainMaterialBillDao, MainMaterialBill> implements MaterialBillBaseService {

    @Resource
    private MainMaterialBillDao materialBillDao;
    @Resource
    private SysReportTimeDao sysReportTimeDao;
    @Resource
    private MainMaterialWeightDao materialWeightDao;
    @Resource
    private MainMaterialContractPriceDao materialContractPriceDao;
    @Resource
    private MainMaterialDao materialDao;
    @Resource
    private OaSupplierDao supplierDao;
    @Resource
    private SysOriginDao originDao;
    @Resource
    private DataSourceInfoDao dsDao;
    @Resource
    private MainMaterialTransportCarDao materialTransportCarDao;

    /**
     * 分页方法
     * @param dto
     * @return
     */
    public IPage<MainMaterialBillVO> page(MainMaterialBillDTO dto) {
        IPage<MainMaterialBillVO>  resultPage = new Page<>();
        PageHelper.offsetPage(dto.getOffsetSize(), dto.getLimit());
        QueryWrapper<MainMaterialBill> queryWrapper = new QueryWrapper<>();
        //类型
        if(ObjectUtil.isNotEmpty(dto.getType())){
            queryWrapper.lambda().eq(MainMaterialBill::getType,dto.getType());
        }
        //公司ID
        if(ObjectUtil.isNotEmpty(dto.getOrgId())){
            queryWrapper.lambda().eq(MainMaterialBill::getOrgId,dto.getOrgId());
        }
        //供应商ID
        if(ObjectUtil.isNotEmpty(dto.getSupplierId())){
            queryWrapper.lambda().eq(MainMaterialBill::getSupplierId,dto.getSupplierId());
        }
        //材料ID
        if(ObjectUtil.isNotEmpty(dto.getMaterialId())){
            queryWrapper.lambda().eq(MainMaterialBill::getMaterialId,dto.getMaterialId());
        }
        //费用类型
        if(ObjectUtil.isNotEmpty(dto.getPriceType())){
            queryWrapper.lambda().eq(MainMaterialBill::getPriceType,dto.getPriceType());
        }
        //是否结算
        if(ObjectUtil.isNotEmpty(dto.getIsBill())){
            queryWrapper.lambda().eq(MainMaterialBill::getIsBill,dto.getIsBill());
        }
        //status
        if(ObjectUtil.isNotEmpty(dto.getStatus())){
            queryWrapper.lambda().eq(MainMaterialBill::getStatus,dto.getStatus());
        }
        //关键字
        if (StrUtil.isNotEmpty(dto.getSearchVal())){
            String searchVal = dto.getSearchVal();
            queryWrapper.lambda().and(p -> p.like(MainMaterialBill::getSupplier, searchVal).or().like(MainMaterialBill::getMaterial, searchVal).or().like(MainMaterialBill::getChecker, searchVal).or().like(MainMaterialBill::getFinance,searchVal).or().like(MainMaterialBill::getRemark,searchVal));
        }
        queryWrapper.lambda().orderByDesc(BaseEntity::getCreateTime);
        IPage<MainMaterialBill> iPage = materialBillDao.selectPage(new Page<>(dto.getOffsetSize(), dto.getLimit()), queryWrapper);
        BeanUtil.copyProperties(iPage,resultPage);
        /**分页插件**/
        if (ObjectUtil.isNotEmpty(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                resultPage.setTotal(pageInfo.getTotal());
            if(CollUtil.isNotEmpty(iPage.getRecords())){
                List<MainMaterialBill> records = iPage.getRecords();
                List<MainMaterialBillVO> resultRecord = new ArrayList<>();
                for (MainMaterialBill mainMaterial : records){
                    MainMaterialBillVO mainMaterialVO = BeanUtil.copyProperties(mainMaterial, MainMaterialBillVO.class);
                    resultRecord.add(mainMaterialVO);
                }
                resultPage.setRecords(resultRecord);
            }
        }
        return resultPage;
    }

    /**
     * 新增方法
     * @param dto
     * @return
     */
    public RestResultDto saveBill(MainMaterialBillAddDTO dto,CacheUser user){
        MainMaterialBill tempBill = BeanUtil.copyProperties(dto, MainMaterialBill.class);
        Date nowDate = new Date();
        if (StringUtils.isNull(dto.getIsCloud()) || dto.getIsCloud().intValue() == 1) {//本地
            QueryWrapper<MainMaterialBill> query = new QueryWrapper<>();
            query.eq("status", 0);
            query.eq("org_id", dto.getOrgId());
            query.eq("today", dto.getToday());
            query.eq("is_check", 1);
            Integer checkTotal = materialBillDao.selectCount(query);
            if (checkTotal > 0)
                throw new MessageCenterException(dto.getToday() + "材料结算报表已审核,不支持新增");

            DataSourceInfo ds = dsDao.queryDSByOriginIdV1(dto.getOrgId(),DataBaseEnum.MYSQL.getCode());
            if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
                throw new MessageCenterException("ERP数据源错误");
            MainMaterialBill takeBill = materialBillDao.findTakeSupplier(ds.getCode(), dto.getOrgId(), dto.getSupplierId(),
                    dto.getMaterialId(), dto.getTransportId(), dto.getType(),
                    dto.getPriceType(), dto.getTakeTime(), dto.getPrice(), dto.getToday());
            if (takeBill != null && (dto.getType() == MaterialContractTypeEnum.YSC.getCode()
                    || dto.getType() == MaterialContractTypeEnum.YSS.getCode())) {
                takeBill.setIsAuto(1);
                takeBill.setUpdateTime(nowDate);
                takeBill.setUpdator(user.getName());
                takeBill.setBillWeightType(dto.getBillWeightType());
                takeBill.setWeight(dto.getWeight());
                takeBill.setSupplierWeight(dto.getSupplierWeight());
                takeBill.setRemark(dto.getRemark());
                takeBill.setPriceRemark(dto.getPriceRemark());
                Integer code = materialBillDao.updateById(takeBill);
                if (code > 0)
                    return RestResultDto.success("更新成功");
            } else {
                tempBill.setStatus(0);
                tempBill.setCreateTime(nowDate);
                tempBill.setCreator(user.getName());
                Integer code = materialBillDao.insert(tempBill);
                if (code > 0)
                    return RestResultDto.success("更新成功");
            }
            return RestResultDto.fail("更新失败");
        } else if (dto.getIsCloud().intValue() == 0) {
            if (StringUtils.isNull(dto.getOrgId()))
                throw new MessageCenterException("公司信息错误");
            DataSourceInfo ds = dsDao.queryDSByOriginIdV1(dto.getOrgId(),DataBaseEnum.MYSQL.getCode());
            if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
                throw new MessageCenterException("ERP数据源错误");
            Integer checkTotal = materialBillDao.findCheckTotal(ds.getCode(), dto.getOrgId(), dto.getToday(), 1, null);
            if (checkTotal > 0)
                throw new MessageCenterException(dto.getToday() + "材料结算报表已审核,不支持新增");
            checkTotal = materialBillDao.findCheckTotal(ds.getCode(), dto.getOrgId(), dto.getToday(), null, 1);
            if (checkTotal > 0)
                throw new MessageCenterException(dto.getToday() + "材料结算报表已审核,不支持新增");
            MainMaterialBill takeBill = materialBillDao.findTakeSupplier(ds.getCode(), dto.getOrgId(), dto.getSupplierId(),
                    dto.getMaterialId(), dto.getTransportId(), dto.getType(),
                    dto.getPriceType(), dto.getTakeTime(), dto.getPrice(), dto.getToday());
            if (takeBill != null && (dto.getType() == MaterialContractTypeEnum.YSC.getCode()
                    || dto.getType() == MaterialContractTypeEnum.YSS.getCode())) {
                takeBill.setIsAuto(1);
                takeBill.setUpdateTime(nowDate);
                takeBill.setUpdator(user.getName());
                takeBill.setBillWeightType(dto.getBillWeightType());
                takeBill.setWeight(dto.getWeight());
                takeBill.setSupplierWeight(dto.getSupplierWeight());
                takeBill.setRemark(dto.getRemark());
                takeBill.setPriceRemark(dto.getPriceRemark());
                Integer code = materialBillDao.updateCloudBill(ds.getCode(), takeBill);
                if (code > 0) {
                    String updateSql = "update main_material_bill set is_auto = 1,updator= ?,update_time= ?," +
                            "bill_weight_type= ?,weight= ?,supplier_weight= ?,remark= ?, price_remark= ? where id = ?";
                    Object[] objs = {user.getName(),DateUtil.convertString(nowDate),dto.getBillWeightType(),
                            dto.getWeight(), dto.getSupplierWeight(), dto.getRemark(), dto.getPriceRemark(), takeBill.getId()};
                    JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                    code = jdbcTemplate.update(updateSql, objs);
                    return RestResultDto.success("更新成功");
                }
            } else {
                String insertSql = "INSERT INTO main_material_bill (org_id,org_name,supplier_id,supplier,transport_id,transport,today,\n" +
                        " start_time,end_time,material_id,material,supplier_weight,weight,\n" +
                        " take_time,price,type,price_type,is_bill,is_check,checker,check_time,\n" +
                        " is_finance,finance,finance_time,status,remark,creator,create_time,\n" +
                        " updator,update_time,bill_weight_type,price_remark,is_auto) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," +
                        "?,?,?,?,?,?,?,?,?)";
                Object[] objs = {tempBill.getOrgId(),tempBill.getOrgName(),tempBill.getSupplierId(),tempBill.getSupplier(),
                        tempBill.getTransportId(),tempBill.getTransport() ,tempBill.getToday(),tempBill.getStartTime(),
                        tempBill.getEndTime(),tempBill.getMaterialId(),tempBill.getMaterial(),tempBill.getSupplierWeight(),
                        tempBill.getWeight(),tempBill.getTakeTime(),tempBill.getPrice(),tempBill.getType(),tempBill.getPriceType() ,
                        tempBill.getIsBill(),0, tempBill.getChecker(),null,0, tempBill.getFinance(),null,0,
                        tempBill.getRemark(), tempBill.getCreator(),DateUtil.convertString(nowDate),"",null,
                        tempBill.getBillWeightType(), tempBill.getPriceRemark(),tempBill.getIsAuto()};

                KeyHolder keyHolder = new GeneratedKeyHolder();
                JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                jdbcTemplate.update(new PreparedStatementCreator() {
                    @Override
                    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                        PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"ID"});
                        for (int i = 0; i < objs.length; i++) {
                            ps.setObject(i + 1, objs[i]);
                        }
                        return ps;
                    }
                }, keyHolder);
                Long taskId = keyHolder.getKey().longValue();
                if (taskId < 1) {
                    throw new MessageCenterException("新增本地结算数据错误");
                }
                List<MainMaterialBill> billList = new ArrayList<>();
                tempBill.setIsAuto(1);
                tempBill.setId(taskId);
                tempBill.setCreateTime(nowDate);
                tempBill.setCreator(user.getName());
                billList.add(tempBill);
                Integer code = materialBillDao.saveBatch(ds.getCode(), billList);
                if (code > 0)
                    return RestResultDto.success("添加成功~！");
                throw new MessageCenterException("添加失败");
            }
        }
        throw new MessageCenterException("添加数据源类型错误");
    }

    /**
     * 修改方法
     * @param dto
     * @return
     */
    public RestResultDto updateBill(MainMaterialBillAddDTO dto, CacheUser user){
        Date nowDate = new Date();
        if (StringUtils.isNull(dto.getIsCloud()) || dto.getIsCloud().intValue() == 1) {//本地
            MainMaterialBill mainMaterialBill = detailByid(dto.getId());
            if (mainMaterialBill == null)
                throw new MessageCenterException("更新数据不存在");
            if (mainMaterialBill.getIsCheck() == 1)
                throw new MessageCenterException("该数据已材料统计审核");
            if (mainMaterialBill.getIsFinance() == 1)
                throw new MessageCenterException("该数据已财务统计审核");
            BeanUtil.copyProperties(dto, mainMaterialBill);
            mainMaterialBill.setUpdator(user.getName());
            mainMaterialBill.setIsAuto(1);
            mainMaterialBill.setUpdateTime(new Date());
            return RestResultDto.success(updateById(mainMaterialBill));
        } else if (dto.getIsCloud().intValue() == 0) {
            DataSourceInfo ds = dsDao.queryDSByOriginIdV1(dto.getOrgId(),DataBaseEnum.MYSQL.getCode());
            if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
                throw new MessageCenterException("ERP数据源错误");
            MainMaterialBill mainMaterialBill = materialBillDao.findCloudById(ds.getCode(), dto.getId());
            if (mainMaterialBill == null)
                throw new MessageCenterException("更新数据不存在");
            if (mainMaterialBill.getIsCheck() == 1)
                throw new MessageCenterException("该数据已材料统计审核");
            if (mainMaterialBill.getIsFinance() == 1)
                throw new MessageCenterException("该数据已财务统计审核");
            MainMaterialBill materialBill = new MainMaterialBill();
            materialBill.setIsBill(dto.getIsBill());
            materialBill.setUpdator(user.getName());
            materialBill.setUpdateTime(nowDate);
            materialBill.setId(dto.getId());
            materialBill.setIsAuto(1);
            materialBill.setOrgId(dto.getOrgId());
            if (StringUtils.isNull(dto.getOrgId()))
                throw new MessageCenterException("公司信息错误");
            Integer code = materialBillDao.updateCloudBill(ds.getCode(), materialBill);
            if (code < 1)
                throw new MessageCenterException("获取到更新信息或该数据已被审核");
            String updateSql = "update main_material_bill set updator = ?, update_time = ?,\n" +
                    " is_bill = ?,is_auto = 1 where id = ?";
            Object[] objs = {user.getName(),DateUtil.convertString(nowDate),dto.getIsBill(), dto.getId()};
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            code = jdbcTemplate.update(updateSql, objs);
            return RestResultDto.success("更新成功~！");
        }
        throw new MessageCenterException("作废数据源类型错误");
    }

    /**
     * 状态更新
     * @param dto
     * @return
     */
    public RestResultDto updateStatus(MainMaterialBillAddDTO dto,CacheUser user) {
        Date nowDate = new Date();
        if (StringUtils.isNull(dto.getIsCloud()) || dto.getIsCloud().intValue() == 1) {//本地
            MainMaterialBill mainMaterialBill = detailByid(dto.getId());
            if (mainMaterialBill == null)
                throw new MessageCenterException("更新数据不存在");
            if (mainMaterialBill.getIsCheck() == 1)
                throw new MessageCenterException("该数据材料统计已审核");
            if (mainMaterialBill.getIsFinance() == 1)
                throw new MessageCenterException("该数据财务统计已审核");
            mainMaterialBill.setStatus(dto.getStatus());
            mainMaterialBill.setUpdator(user.getName());
            mainMaterialBill.setUpdateTime(new Date());
            Integer code = materialBillDao.updateById(mainMaterialBill);
            if (code > 0)
                return RestResultDto.success("更新成功");
            return RestResultDto.fail("更新失败");
        } else if (dto.getIsCloud().intValue() == 0) {
            if (StringUtils.isNull(dto.getOrgId()))
                throw new MessageCenterException("公司信息错误");
            DataSourceInfo ds = dsDao.queryDSByOriginIdV1(dto.getOrgId(),DataBaseEnum.MYSQL.getCode());
            if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
                throw new MessageCenterException("ERP数据源错误");

            if (!StringUtils.isNull(dto.getId())) {//单条数据更新
                MainMaterialBill mainMaterialBill = materialBillDao.findCloudById(ds.getCode(), dto.getId());
                if (mainMaterialBill == null)
                    throw new MessageCenterException("更新数据不存在");
                if (mainMaterialBill.getIsCheck() == 1)
                    throw new MessageCenterException("该数据材料统计已审核");
                if (mainMaterialBill.getIsFinance() == 1)
                    throw new MessageCenterException("该数据财务统计已审核");
                mainMaterialBill.setStatus(dto.getStatus());
                mainMaterialBill.setUpdator(user.getName());
                mainMaterialBill.setUpdateTime(new Date());
                Integer code = materialBillDao.updateCloudBillStatus(ds.getCode(), mainMaterialBill);
                if (code < 1)
                    throw new MessageCenterException("获取到更新信息或该数据已被审核");
                String updateSql = "update main_material_bill set updator = ?, update_time = ?,\n" +
                        " status = ? where id = ?";
                Object[] objs = {user.getName(),DateUtil.convertString(nowDate),dto.getStatus(), dto.getId()};
                JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                code = jdbcTemplate.update(updateSql, objs);
                if (code > 0)
                    return RestResultDto.success("更新成功~！");
                throw new MessageCenterException("更新失败");
            } else {//批量数据更新
                Integer checkTotal = materialBillDao.findCheckTotal(ds.getCode(), dto.getOrgId(), dto.getToday(), 1, null);
                if (checkTotal > 0)
                    throw new MessageCenterException(dto.getToday() + "购进报表已审核,不提供作废");
                checkTotal = materialBillDao.findCheckTotal(ds.getCode(), dto.getOrgId(), dto.getToday(), null, 1);
                if (checkTotal > 0)
                    throw new MessageCenterException(dto.getToday() + "购进报表已审核,不提供作废");
                if (StringUtils.isNull(dto.getToday()))
                    throw new MessageCenterException("更新结算周期错误");
                String updateSql = "update main_material_bill set updator = '" + user.getName() + "', update_time = '"
                        + DateUtil.convertString(nowDate) + "', status = " + dto.getStatus() + " " +
                        " where today = '" + dto.getToday() + "' and is_auto = 0 and org_id = " + dto.getOrgId();
                MainMaterialBill updateBill = new MainMaterialBill();
                updateBill.setUpdator(user.getName());
                updateBill.setUpdateTime(nowDate);
                updateBill.setStatus(dto.getStatus());
                updateBill.setToday(dto.getToday());
                updateBill.setOrgId(dto.getOrgId());
//                if (!StringUtils.isNull(dto.getIsAuto()) && dto.getIsAuto() == 1) {
//                    updateSql += " and is_auto = 0 ";
//                    updateBill.setIsAuto(0);
//                }
                if (!StringUtils.isNull(dto.getSupplierId())) {
                    updateBill.setSupplierId(dto.getSupplierId());
                    updateSql += " and supplier_id = " + dto.getSupplierId();
                }
                if (!StringUtils.isNull(dto.getMaterialId())) {
                    updateBill.setMaterialId(dto.getMaterialId());
                    updateSql += " and material_id = " + dto.getMaterialId();
                }
                if (!StringUtils.isNull(dto.getType())) {
                    updateBill.setType(dto.getType());
                    updateSql += " and type = " + dto.getType();
                }
                Integer code = materialBillDao.updateCloudBillStatus(ds.getCode(), updateBill);
//                if (code < 1)
//                    throw new MessageCenterException("获取到更新信息或该数据已被审核");
                JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
                code = jdbcTemplate.update(updateSql);
//                if (code > 0)
                    return RestResultDto.success("同步成功,请稍后再试~！");
//                throw new MessageCenterException("更新失败");
            }
        }
        throw new MessageCenterException("作废数据源类型错误");
    }
    /**
     * 查询购进合计
     * @param searchVal
     * @param today
     * @param startTime
     * @param type 0材料 1运输
     * @param status
     * @param supplierId
     * @param materialId
     * @param materialType 材料大类名称 SysMaterialTypeEnum
     * @return
     */
    public MainMaterialBill findBuySum(Long orgId,String searchVal, String today, String startTime, String endTime, Integer type,
                                  Integer status, Long supplierId, Long materialId,Integer materialType, Integer isBill) {
        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId, DataBaseEnum.MYSQL.getCode());
        if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
            return null;
        QueryWrapper<MainMaterialBillVo> billQuery = initFullParam(searchVal, today, startTime, endTime, type,
                status, supplierId, materialId, orgId,materialType, isBill);
        List<MainMaterialBill> billList = materialBillDao.findBuySum(ds.getCode(), billQuery);
        if (billList == null || billList.size() == 0)
            return null;
        return billList.get(0);
    }

    /**
     * 查询购进报表明细
     * @param searchVal
     * @param today
     * @param startTime
     * @param endTime
     * @param type 0材料 1运输
     * @param status
     * @param supplierId
     * @param materialId
     * @param materialType 材料大类名称 SysMaterialTypeEnum
     * @param offset
     * @param limit
     * @return
     */
    public IPage findBuyPage(Long orgId,String searchVal, String today, String startTime, String endTime, Integer type,
                             Integer status, Long supplierId, Long materialId,Integer materialType,
                             Integer isBill, Integer offset, Integer limit) {
        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId,DataBaseEnum.MYSQL.getCode());
        if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
            throw new MessageCenterException("ERP数据源错误");
        QueryWrapper<MainMaterialBillVo> billQuery = initFullParam(searchVal, today, startTime, endTime, type,
                status, supplierId, materialId, orgId,materialType, isBill);
        PageHelper.offsetPage(offset, limit);
        IPage<MainMaterialBillVo> iPage = materialBillDao.findBuyPage(new Page<>((offset + limit) /limit, limit),ds.getCode(), billQuery);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    /**
     * 审核购进明细报表
     * @param orgId
     * @param today 时间点
     * @param creator
     * @param type 0 材料统计 1 财务
     * @return
     */
    public RestResultDto examineBuy(Long orgId, String today, String creator, Integer type) {
        if (StringUtils.isAllParamNull(orgId, today, type))
            throw new MessageCenterException("审核材料购进表参数错误");

        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId,DataBaseEnum.MYSQL.getCode());
        if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
            throw new MessageCenterException("ERP数据源错误");
        Date nowDate = new Date();
        String nowTime = DateUtil.convertString(nowDate);
        String updateSql = "update main_material_bill ";
        Integer code = -1;
        if (type == 0) {
            Integer total = materialBillDao.findCheckTotal(ds.getCode(), orgId, today, 0, null);
            if (total < 1)
                throw new MessageCenterException("没有审核的数据");
            MainMaterialBill bill = new MainMaterialBill();
            bill.setOrgId(orgId);
            bill.setToday(today);
            bill.setUpdateTime(nowDate);
            bill.setUpdator(creator);
            bill.setIsCheck(1);
            bill.setChecker(creator);
            bill.setCheckTime(nowDate);
            code = materialBillDao.updateCloudExamineBill(ds.getCode(), bill);
            if (code < 1)
                throw new MessageCenterException("没有未审核数据记录");
            updateSql += "set updator = '" + creator + "',update_time='" + nowTime + "',checker = '" + creator
                    + "',is_check = 1,check_time = '" + nowTime + "' " +
                    " where today = '" + today + "' and org_id = " + orgId;
        } else if (type == 1) {
            Integer total = materialBillDao.findCheckTotal(ds.getCode(), orgId, today, 0, null);
            if (total > 0)
                throw new MessageCenterException("材料统计未审核,请通知材料统计先行审核");
            total = materialBillDao.findCheckTotal(ds.getCode(), orgId, today, 1, 0);
            if (total < 1)
                throw new MessageCenterException("没有未审核数据记录");

            MainMaterialBill bill = new MainMaterialBill();
            bill.setOrgId(orgId);
            bill.setToday(today);
            bill.setUpdateTime(nowDate);
            bill.setUpdator(creator);
            bill.setIsFinance(1);
            bill.setFinance(creator);
            bill.setFinanceTime(nowDate);
            code = materialBillDao.updateCloudExamineBill(ds.getCode(), bill);
            if (code < 1)
                throw new MessageCenterException("没有未审核数据记录");
            updateSql += "set updator = '" + creator + "',update_time='" + nowTime + "',finance = '" + creator
                    + "',is_finance = 1,finance_time = '" + nowTime + "' " +
                    " where today = '" + today + "' and org_id = " + orgId;
        }
        if (code > 0) {
            JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
            code = jdbcTemplate.update(updateSql);
            return RestResultDto.success("审核成功");
        }
        throw new MessageCenterException("审核类型错误");
    }

    /**
     * 查询购进报表汇总
     * @param orgId
     * @param searchVal
     * @param today
     * @param startTime
     * @param endTime
     * @param type 0材料 1运输
     * @param status
     * @param supplierId
     * @param materialId
     * @param materialType 材料大类名称 SysMaterialTypeEnum
     * @return
     */
    public List<MainMaterialBillVo> findBuyData(Long orgId,String searchVal, String today, String startTime, String endTime,
                                                Integer type, Integer status, Long supplierId, Long materialId,
                                                Integer materialType, Integer isBill) {
        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId,DataBaseEnum.MYSQL.getCode());
        if (ds == null || ds.getStatus() == 1 || ds.getType() != 0)
            throw new MessageCenterException("ERP数据源错误");
        QueryWrapper<MainMaterialBillVo> billQuery = initFullParam(searchVal, today, startTime, endTime, type,
                status, supplierId, materialId, orgId,materialType, isBill);
        List<MainMaterialBillVo> billVoList = materialBillDao.findBuyPage(ds.getCode(), billQuery);
        if (billVoList == null || billVoList.size() == 0)
            return null;
        Map<Integer, String> materialTypeMap = new HashMap<>();
        for (int i = 0; i < MaterialBreedTypeEnum.values().length; i++) {
            materialTypeMap.put(MaterialBreedTypeEnum.values()[i].getCode(), MaterialBreedTypeEnum.values()[i].getDescription());
        }

        List<MainMaterialBillVo> resultList = new ArrayList<>();
//        Double tempAvgPrice = 0.0;//平均单价小计
        Double tempSumWeight = 0.0;//小计吨位
        Double tempSumPrice = 0.0;//总价
//        Double avgPrice = 0.0;//平均单价
        Double sumWeight = 0.0;//总吨位
        Double sumPrice = 0.0;//总价
        Integer calcMaterialType = -1;//材料类型
        for (int i = 0; i < billVoList.size(); i++) {
            MainMaterialBillVo billVo = billVoList.get(i);
            if (calcMaterialType == -1)
                calcMaterialType = billVo.getBreedType();
            if (i > 0 && !StringUtils.isNull(billVo.getBreedType()) && calcMaterialType.intValue() != billVo.getBreedType()) {//属于另外一种材料
                MainMaterialBillVo tempBillVo = new MainMaterialBillVo();
                String showMaterialType = "";
                if (!StringUtils.isNull(materialTypeMap.get(calcMaterialType)))
                    showMaterialType = "[" + materialTypeMap.get(calcMaterialType) + "]";
                tempBillVo.setMaterial(showMaterialType + "<小计>");
                tempBillVo.setWeight(StringUtils.formatDouble(tempSumWeight * 1000, 2));//反算成公斤为单位
                tempBillVo.setSupplierWeight(StringUtils.formatDouble(tempSumWeight * 1000, 2));//反算成公斤为单位
                if (!StringUtils.isNull(tempSumWeight) && !StringUtils.isNull(tempSumPrice)
                        && tempSumPrice != 0 && tempSumWeight != 0) {
                    tempBillVo.setPrice(StringUtils.formatDouble(tempSumPrice / tempSumWeight , 2));
                } else {
                    tempBillVo.setPrice(0.0);
                }
                tempBillVo.setTotalPrice(StringUtils.formatDouble(tempSumPrice, 2));
                tempSumWeight = 0.0;
                tempSumPrice = 0.0;
                calcMaterialType = billVo.getBreedType();
                resultList.add(tempBillVo);
            }
            Double weight = billVo.getWeight();
            if (!StringUtils.isNull(billVo.getBillWeightType()) && billVo.getBillWeightType().intValue() == 1)
                weight = billVo.getSupplierWeight();
            weight = StringUtils.formatDouble(weight / 1000, 2);
            Double tempPrice = StringUtils.formatDouble(billVo.getPrice() * weight, 2);
            if (billVo.getType().intValue() == 0) {//主材累计吨位
                sumWeight += weight;
                tempSumWeight += weight;
            } else {
                if (!StringUtils.isNull(type) && (type == 1 || type == 2)) {
                    sumWeight += weight;
                    tempSumWeight += weight;
                }
                billVo.setSupplier(StringUtils.convertString(billVo.getTransport()) + "<" + StringUtils.convertString(billVo.getSupplier()) + ">");//重新组装材料供应商
            }
            if (billVo.getIsBill() == 0) {
                tempSumPrice += tempPrice;
                sumPrice += tempPrice;
            }
            billVo.setTotalPrice(StringUtils.formatDouble(tempPrice, 2));
            resultList.add(billVo);
        }
        MainMaterialBillVo tempBillVo = new MainMaterialBillVo();
        String showMaterialType = "";
        if (!StringUtils.isNull(materialTypeMap.get(calcMaterialType)))
            showMaterialType = "[" + materialTypeMap.get(calcMaterialType) + "]";
        tempBillVo.setMaterial(showMaterialType + "<小计>");
//        tempBillVo.setMaterial("<小计>");
        tempBillVo.setWeight(StringUtils.formatDouble(tempSumWeight * 1000, 2));//反算成公斤为单位
        tempBillVo.setSupplierWeight(StringUtils.formatDouble(tempSumWeight * 1000, 2));//反算成公斤为单位
        if (StringUtils.isNull(tempSumWeight) || tempSumWeight == 0)
            tempBillVo.setPrice(0.0);
        else
            tempBillVo.setPrice(StringUtils.formatDouble(tempSumPrice / tempSumWeight , 2));
        tempBillVo.setTotalPrice(StringUtils.formatDouble(tempSumPrice, 2));

        resultList.add(tempBillVo);
        tempBillVo = new MainMaterialBillVo();
        tempBillVo.setMaterial("<合计>");
        tempBillVo.setWeight(StringUtils.formatDouble(sumWeight * 1000, 2));//反算成公斤为单位
        tempBillVo.setSupplierWeight(StringUtils.formatDouble(sumWeight * 1000, 2));//反算成公斤为单位
        if (StringUtils.isNull(sumPrice) || sumWeight == 0)
            tempBillVo.setPrice(0.0);
        else
            tempBillVo.setPrice(StringUtils.formatDouble(sumPrice / sumWeight , 2));
//        tempBillVo.setPrice(StringUtils.formatDouble(sumPrice / sumWeight , 2));
        tempBillVo.setTotalPrice(StringUtils.formatDouble(sumPrice, 2));
        resultList.add(tempBillVo);
        if (resultList == null || resultList.size() == 0)
            return null;
        return resultList;
    }

    /**
     * 运输购进数据
     * @param today
     * @param orgId
     * @param type
     * @param supplierId
     * @param materialId
     * @param creator
     * @param isCloud
     * @return
     */
    public Map<String, MainMaterialBill> calcTransportMaterialDetail(String today, Long orgId, Integer type, Long supplierId,
                                              Long materialId, String creator, Integer isCloud) {
        if (StringUtils.isAllParamNull(today, orgId))
            throw new MessageCenterException("参数错误");
        if (StringUtils.isNull(type))
            type = MaterialContractTypeEnum.ZC.getCode();
        SysOrigin origin = originDao.selectById(orgId);
        if (origin == null)
            throw new MessageCenterException("公司信息错误");
        SysReportTime reportTime = sysReportTimeDao.findTodayByOne(today);
        if (reportTime == null || reportTime.getStatus() == 1)
            throw new MessageCenterException("统计报表时间不存在或已被删除");
        Date startDate = DateUtil.convertDate(reportTime.getStartTime());
        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId,DataBaseEnum.MYSQL.getCode());
        if (ds == null)
            throw new MessageCenterException("统计公司数据源不存在");
        List<MainMaterialWeightVo> weightList = null;
        if (StringUtils.isNull(isCloud))
            isCloud = 1;
        JdbcTemplate jdbcTemplate = null;
        if (isCloud == 0) {
            jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
//            String sql = "select supplier_id,material_id,net_weight,out_time,supplier_net_weight from main_material_weight\n" +
//                    "where org_id = " + orgId + " and status = 0 and car_type = 2 \n" +
//                    "and weight_type = 1 and net_weight > 0\n" +
//                    "and is_bill = 0 and out_time >= '" + reportTime.getStartTime() + "' and out_time < '" + reportTime.getEndTime() + "' ";
            String sql = "select a.supplier_id,a.material_id,a.net_weight,a.out_time,a.supplier_net_weight,b.bill_weight_type,a.car_no\n" +
                    " from main_material_weight a \n" +
                    " LEFT JOIN (select material_id,bill_weight_type from main_material \n" +
                    " where org_id = " + orgId + " and status = 0) b on a.material_id = b.material_id\n" +
                    " where a.org_id = " + orgId + " and a.status = 0 and a.car_type = 2 \n" +
                    " and a.weight_type = 1 and a.net_weight > 0\n" +
                    " and a.is_bill = 0 and a.out_time >= '" + reportTime.getStartTime()
                    + "' and a.out_time < '" + reportTime.getEndTime() + "' ";

            if (!StringUtils.isNull(supplierId)) {
                sql += "and (a.supplier_id in (select supplier_id from main_material_contract_price " +
                        " where transport_id = " + supplierId + " and org_id = " + orgId + " and status = 0 " +
                        " and transport_id is not null GROUP BY supplier_id) or a.supplier_id = " + supplierId + ") ";
            }
            if (!StringUtils.isNull(materialId))
                sql += "and a.material_id = " + materialId + " ";
            sql += " order by out_time";
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
            if (mapList != null && mapList.size() > 0)
                weightList = StringUtils.fastClassList(mapList, MainMaterialWeightVo.class);
        } else {
            weightList = materialWeightDao.findSupplierWeight(ds.getCode(), orgId, supplierId, materialId, 2,
                    1,reportTime.getStartTime(), reportTime.getEndTime());
        }

        if (weightList == null || weightList.size() == 0)
            throw new MessageCenterException(today + "计算周期内没有任何过磅数据");
        Date nowDate = new Date();
        QueryWrapper<MainMaterial> materialQuery = new QueryWrapper<>();
        materialQuery.eq("status", 0);
        materialQuery.eq("org_id", orgId);
        if (!StringUtils.isNull(supplierId))
            materialQuery.inSql("material_id", "select material_id from main_material_contract_price " +
                    " where status = 0 and org_id = " + orgId
                    + " and (transport_id = " + supplierId + " or supplier_id = " +supplierId + ")");
        List<MainMaterial> materialList = materialDao.selectList(materialQuery);
        if (materialList == null || materialList.size() == 0)
            throw new MessageCenterException("没有获取到材料信息");
        QueryWrapper<OaSupplier> supplierQuery = new QueryWrapper<>();
        supplierQuery.eq("status", 0);
        supplierQuery.inSql("id", "select sid from oa_material_contract where status = 0 and org_id = " + orgId);
        if (!StringUtils.isNull(supplierId)) {
            supplierQuery.and(orderWrapper -> orderWrapper.eq("id", supplierId).or()
                    .inSql("id", "select transport_id from main_material_contract_price \n" +
                            " where  org_id = " + orgId + " and status = 0 and supplier_id = " + supplierId +
                            " and transport_id is not null GROUP BY transport_id").or()
                    .inSql("id", "select supplier_id from main_material_contract_price \n" +
                            " where  org_id = " + orgId + " and status = 0 and transport_id = " + supplierId +
                            "  GROUP BY supplier_id"));
        }
        List<OaSupplier> supplierList = supplierDao.selectList(supplierQuery);
        if (supplierList == null || supplierList.size() == 0)
            throw new MessageCenterException("没有获取到供应商信息");
        Map<Long, MainMaterial> materialMap = new HashMap<>();
        Map<Long, OaSupplier> supplierMap = new HashMap<>();
        for (int i = 0; i < materialList.size(); i++) {//材料列表
            MainMaterial mainMaterial = materialList.get(i);
            materialMap.put(mainMaterial.getMaterialId(), mainMaterial);
        }
        for (int i = 0; i < supplierList.size(); i++) {//供应商列表
            OaSupplier supplier = supplierList.get(i);
            supplierMap.put(supplier.getId(), supplier);
        }

        Map<String, MainMaterialBill> billMap = new HashMap<>();//key 的规则 合同_供应商_运输商_材料_价格生效时间_价格
        for (int i = 0; i < weightList.size(); i++) {
            MainMaterialWeightVo weightVo = weightList.get(i);
            Long tempSupplierId = weightVo.getSupplierId();
            materialId = weightVo.getMaterialId();
            Double tempNetWeight = weightVo.getNetWeight();
            String tempCarNo = weightVo.getCarNo();
            Double tempSupplierNetWeight = weightVo.getSupplierNetWeight();
            Integer billWeightType = weightVo.getBillWeightType();
            String outTime = DateUtil.convertString(weightVo.getOutTime());
            MaterialTransportPriceVo transportPriceVo = materialTransportCarDao.findTransportPrice(ds.getCode(),
                    supplierId, materialId, type, tempCarNo, outTime);
            if (transportPriceVo == null || StringUtils.isNull(transportPriceVo.getTransportId()))
                continue;//如果运输费用不存在或运输供应商不存在则跳过
            Long transportId = transportPriceVo.getTransportId();
            Double price = transportPriceVo.getPrice();
            Long contractId = transportPriceVo.getContractId();
            String takeTime = transportPriceVo.getTakeTime();
            Integer isBill = BillEnum.JS.getCode();
            if (!StringUtils.isNull(transportPriceVo.getIsBill()))
                isBill = transportPriceVo.getIsBill();
            String supplier = "";
            String transport = "";
            if (!StringUtils.isNull(transportPriceVo.getBillWeightType()))
                billWeightType = transportPriceVo.getBillWeightType();
            String nameNorms = "";
            if (materialMap.containsKey(materialId))
                nameNorms = materialMap.get(materialId).getNameNorms();
            if (supplierMap.containsKey(tempSupplierId))
                supplier = supplierMap.get(tempSupplierId).getFullName();
            if (supplierMap.containsKey(transportId))
                transport = supplierMap.get(transportId).getFullName();
            String key = contractId + "_" + tempSupplierId + "_" + transportId + "_" + materialId + "_"
                    + takeTime + "_" + price;
            if (billMap.containsKey(key)) {
                MainMaterialBill materialBill = billMap.get(key);
                materialBill.setWeight(materialBill.getWeight() + tempNetWeight);
                materialBill.setSupplierWeight(materialBill.getSupplierWeight() + tempSupplierNetWeight);
                billMap.put(key, materialBill);
            } else {
                MainMaterialBill materialBill = new MainMaterialBill(origin.getId(), origin.getOriginName(), tempSupplierId, supplier,
                        transportId, transport, today, reportTime.getStartTime(), reportTime.getEndTime(), materialId, nameNorms,
                        tempSupplierNetWeight, tempNetWeight, takeTime, price, type, BillPriceTypeEnum.JS.getCode(), isBill,
                        CheckEnum.UHE.getCode(), "", null, CheckEnum.UHE.getCode(), "", null);
                materialBill.setBillWeightType(billWeightType);
                materialBill.setIsAuto(0);
                materialBill.setPriceRemark(transportPriceVo.getPriceRemark());
                materialBill.setRemark(transportPriceVo.getRemark());
                materialBill.setStatus(0);
                materialBill.setCreator(creator);
                materialBill.setCreateTime(nowDate);
                billMap.put(key, materialBill);
            }
        }

        return billMap;
    }
    /**
     * 查询是否已审核
     * @param orgId
     * @param today
     * @return
     */
    public Integer findCheck(String dbCode, Long orgId, String today) {
        if (StringUtils.isAllParamNull(orgId, today))
            throw new MessageCenterException("查询审核信息参数错误");
        Integer total = materialBillDao.findCheckTotal(dbCode, orgId, today, 1, null);
        if (total > 0)
            return total;
        total = materialBillDao.findCheckTotal(dbCode, orgId, today, null, 1);
        if (total > 0)
            return total;
        return 0;
    }
    /**
     * 计算供应商购进报表信息
     * @param today 结算月份
     * @param type 类型(0：主材，1：运输)
     * @param supplierId 供应商ID
     * @param materialId 材料ID
     * @param isCloud 0云端 1本地
     * @param creator
     * @return
     */
    public RestResultDto calcMaterialDetail(String today, Long orgId, Integer type, Long supplierId,
                                     Long materialId, String creator, Integer isCloud) {
        if (StringUtils.isAllParamNull(today, orgId))
            throw new MessageCenterException("参数错误");
        if (StringUtils.isNull(type))
            type = MaterialContractTypeEnum.ZC.getCode();
//        if (type == MaterialContractTypeEnum.YSC.getCode())//取消材料运输报表自动计算
//            return RestResultDto.fail("取消自动计算运输报表");
        SysOrigin origin = originDao.selectById(orgId);
        if (origin == null)
            throw new MessageCenterException("公司信息错误");
        SysReportTime reportTime = sysReportTimeDao.findTodayByOne(today);
        if (reportTime == null || reportTime.getStatus() == 1)
            throw new MessageCenterException("统计报表时间不存在或已被删除");
        Date startDate = DateUtil.convertDate(reportTime.getStartTime());
        DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId,DataBaseEnum.MYSQL.getCode());
        if (ds == null)
            throw new MessageCenterException("统计公司数据源不存在");
        Integer checkTotal = materialBillDao.findCheckTotal(ds.getCode(), orgId, today, 1, null);
        if (checkTotal > 0)
            throw new MessageCenterException(today + "材料结算报表已审核,不能再进行系统计算");
        checkTotal = materialBillDao.findCheckTotal(ds.getCode(), orgId, today, null, 1);
        if (checkTotal > 0)
            throw new MessageCenterException(today + "材料结算报表已审核,不能再进行系统计算");

        List<MainMaterialWeightVo> weightList = null;
        if (StringUtils.isNull(isCloud))
            isCloud = 1;
        JdbcTemplate jdbcTemplate = null;
        if (isCloud == 0) {
            jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
//            String sql = "select supplier_id,material_id,net_weight,out_time,supplier_net_weight from main_material_weight\n" +
//                    "where org_id = " + orgId + " and status = 0 and car_type = 2 \n" +
//                    "and weight_type = 1 and net_weight > 0\n" +
//                    "and is_bill = 0 and out_time >= '" + reportTime.getStartTime() + "' and out_time < '" + reportTime.getEndTime() + "' ";
            String sql = "select a.supplier_id,a.material_id,a.net_weight,a.out_time,a.supplier_net_weight,b.bill_weight_type,a.car_no\n" +
                    " from main_material_weight a \n" +
                    " LEFT JOIN (select material_id,bill_weight_type from main_material \n" +
                    " where org_id = " + orgId + " and status = 0) b on a.material_id = b.material_id\n" +
                    " where a.org_id = " + orgId + " and a.status = 0 and a.car_type = 2 \n" +
                    " and a.weight_type = 1 and a.net_weight > 0\n" +
                    " and a.is_bill = 0 and a.out_time >= '" + reportTime.getStartTime()
                    + "' and a.out_time < '" + reportTime.getEndTime() + "' ";

            if (!StringUtils.isNull(type) && (type == 1 || type == 3)) {
                if (!StringUtils.isNull(supplierId)) {
                    sql += " and (a.supplier_id in (select supplier_id from main_material_contract_price " +
                            " where transport_id = " + supplierId + " and org_id = " + orgId + " " +
                            " and status = 0 GROUP BY supplier_id) or a.supplier_id = " + supplierId + ")";
                }
            } else {
                if (!StringUtils.isNull(supplierId))
                    sql += "and a.supplier_id = " + supplierId + " ";
            }
            if (!StringUtils.isNull(materialId))
                sql += "and a.material_id = " + materialId + " ";
            sql += " order by out_time";
            List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
            if (mapList != null && mapList.size() > 0)
                weightList = StringUtils.fastClassList(mapList, MainMaterialWeightVo.class);
        } else {
            weightList = materialWeightDao.findSupplierWeight(ds.getCode(), orgId, supplierId, materialId, 2,
                    1,reportTime.getStartTime(), reportTime.getEndTime());
        }

        if (weightList == null || weightList.size() == 0)
            throw new MessageCenterException(today + "计算周期内没有任何过磅数据");
        QueryWrapper<MainMaterial> materialQuery = new QueryWrapper<>();
        materialQuery.eq("status", 0);
        materialQuery.eq("org_id", orgId);
        if (!StringUtils.isNull(supplierId)) {
            if (!StringUtils.isNull(type) && (type == 1 || type == 3)) {
                materialQuery.inSql("material_id", "select material_id from main_material_contract_price " +
                        " where status = 0 and org_id = " + orgId + " and (transport_id = " + supplierId + " or supplier_id = " + supplierId + ")");
            } else {
                materialQuery.inSql("material_id", "select material_id from main_material_contract_price " +
                        " where status = 0 and org_id = " + orgId + " and supplier_id = " + supplierId);
            }
        }
        List<MainMaterial> materialList = materialDao.selectList(materialQuery);
        if (materialList == null || materialList.size() == 0)
            throw new MessageCenterException("没有获取到材料信息");
        QueryWrapper<OaSupplier> supplierQuery = new QueryWrapper<>();
        supplierQuery.eq("status", 0);
        supplierQuery.inSql("id", "select sid from oa_material_contract where status = 0 and org_id = " + orgId);
        if (!StringUtils.isNull(supplierId))
            supplierQuery.eq("id", supplierId);
        List<OaSupplier> supplierList = supplierDao.selectList(supplierQuery);
        if (supplierList == null || supplierList.size() == 0)
            throw new MessageCenterException("没有获取到供应商信息");
        Map<Long, MainMaterial> materialMap = new HashMap<>();
        Map<Long, OaSupplier> supplierMap = new HashMap<>();
        for (int i = 0; i < materialList.size(); i++) {//材料列表
            MainMaterial mainMaterial = materialList.get(i);
            materialMap.put(mainMaterial.getMaterialId(), mainMaterial);
        }
        for (int i = 0; i < supplierList.size(); i++) {//供应商列表
            OaSupplier supplier = supplierList.get(i);
            supplierMap.put(supplier.getId(), supplier);
        }
        Date nowDate = new Date();
        Map<String, MainMaterialBill> billMap = new HashMap<>();
        if (type == MaterialContractTypeEnum.ZC.getCode() || type == MaterialContractTypeEnum.XS.getCode()
                || type == MaterialContractTypeEnum.JS.getCode()) {//主材
            billMap = calcMaterial(jdbcTemplate, ds, reportTime, materialMap, supplierMap, weightList, origin, today,
                    materialId, supplierId, type, creator, isCloud);
        } else if (type == MaterialContractTypeEnum.YSC.getCode() || type == MaterialContractTypeEnum.YSS.getCode()){
            billMap = calcTransportMaterialDetail(today, orgId, type, supplierId,
                    materialId, creator, isCloud);
        }
        if (billMap != null) {//新增材料购进数据
            List<MainMaterialBill> billList = new ArrayList<>();
            for (String key : billMap.keySet()) {
                billList.add(billMap.get(key));
            }
            if (billList != null && billList.size() > 0) {
                List<MainMaterialBill> insertBillList = new ArrayList<>();
                List<Object[]> insertList = new ArrayList();
                List<Object[]> updateList = new ArrayList();
                for (int i = 0; i < billList.size(); i++) {
                    MainMaterialBill tempBill = billList.get(i);
                    MainMaterialBill materialBill = null;
                    if (type == MaterialContractTypeEnum.ZC.getCode()) {//计算主材
                        materialBill = materialBillDao.findTakeSupplier(ds.getCode(), tempBill.getOrgId(), tempBill.getSupplierId(),
                                tempBill.getMaterialId(), null, type,
                                0, tempBill.getTakeTime(), tempBill.getPrice(), today);
                    } else if (type == MaterialContractTypeEnum.YSC.getCode()) {//运输
                        materialBill = materialBillDao.findTakeSupplier(ds.getCode(), tempBill.getOrgId(), tempBill.getSupplierId(),
                                tempBill.getMaterialId(), tempBill.getTransportId(), type,
                                0, tempBill.getTakeTime(), tempBill.getPrice(), today);
                    }
                    if (materialBill == null) {
//                        List<MainMaterialBill> tempList = new ArrayList<>();
//                        tempList.add(tempBill);
//                        materialBillDao.saveBatch(ds.getCode(),tempList);
                        insertBillList.add(tempBill);
                        Object[] objs = {tempBill.getOrgId(),tempBill.getOrgName(),tempBill.getSupplierId(),tempBill.getSupplier(),
                                tempBill.getTransportId(),tempBill.getTransport() ,tempBill.getToday(),tempBill.getStartTime(),
                                tempBill.getEndTime(),tempBill.getMaterialId(),tempBill.getMaterial(),tempBill.getSupplierWeight(),
                                tempBill.getWeight(),tempBill.getTakeTime(),tempBill.getPrice(),tempBill.getType(),tempBill.getPriceType() ,
                                tempBill.getIsBill(),0, tempBill.getChecker(),null,0, tempBill.getFinance(),null,0,
                                tempBill.getRemark(), tempBill.getCreator(),DateUtil.convertString(nowDate),"",null,
                                tempBill.getBillWeightType(), tempBill.getPriceRemark(), 0};
                        insertList.add(objs);
                    } else {
                        if (materialBill.getIsCheck() == 0 || materialBill.getIsAuto() == 0) {
                            if (!StringUtils.isNull(tempBill.getStartTime()) && !StringUtils.isNull(materialBill.getStartTime())
                                    && materialBill.getStartTime().equals(tempBill.getStartTime()))
                                materialBill.setStartTime(tempBill.getStartTime());
                            if (!StringUtils.isNull(tempBill.getEndTime()) && !StringUtils.isNull(materialBill.getEndTime())
                                    && materialBill.getEndTime().equals(tempBill.getEndTime()))
                                materialBill.setEndTime(tempBill.getEndTime());
                            materialBill.setIsAuto(0);
                            materialBill.setSupplier(tempBill.getSupplier());
                            materialBill.setSupplierId(tempBill.getSupplierId());
                            materialBill.setMaterial(tempBill.getMaterial());
                            materialBill.setMaterialId(tempBill.getMaterialId());
                            materialBill.setWeight(tempBill.getWeight());
                            materialBill.setSupplierWeight(tempBill.getSupplierWeight());
                            materialBill.setBillWeightType(tempBill.getBillWeightType());
                            materialBill.setUpdator(creator);
                            materialBill.setUpdateTime(nowDate);
                            materialBill.setPriceRemark(tempBill.getPriceRemark());
                            materialBillDao.updateCloudBill(ds.getCode(), materialBill);
                            Object[] objs = {creator,DateUtil.convertString(nowDate),tempBill.getEndTime(),
                                    tempBill.getStartTime(),tempBill.getSupplier(),tempBill.getSupplierId(),
                                    tempBill.getTransportId(),tempBill.getTransport() ,
                                    tempBill.getMaterialId(),tempBill.getMaterial(),tempBill.getSupplierWeight(),
                                    tempBill.getWeight(),tempBill.getPrice(),tempBill.getBillWeightType(),
                                    tempBill.getPriceRemark(), tempBill.getId()};
                            updateList.add(objs);
                        }
                    }
                }
                if (insertBillList != null && insertBillList.size() > 0) {

                    Integer resultCode =materialBillDao.saveBatch(ds.getCode(), insertBillList);
                    System.out.println(resultCode);
                }
                if (isCloud == 0) {//如果是云端就修改本地数据
                    String insertSql = "INSERT INTO main_material_bill (org_id,org_name,supplier_id,supplier,transport_id,transport,today,\n" +
                            " start_time,end_time,material_id,material,supplier_weight,weight,\n" +
                            " take_time,price,type,price_type,is_bill,is_check,checker,check_time,\n" +
                            " is_finance,finance,finance_time,status,remark,creator,create_time,\n" +
                            " updator,update_time,bill_weight_type,price_remark, is_auto) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                    String updateSql = "update main_material_bill set updator = ?, update_time = ?,\n" +
                            " end_time = ?, start_time = ?, supplier = ?, supplier_id = ?, transport_id = ?,\n" +
                            " transport = ?, material_id = ?, material = ?,supplier_weight = ?, weight = ?,\n" +
                            " price = ?,bill_weight_type = ?, price_remark=? where id = ? and is_auto = 0";
                    if (insertList != null && insertList.size() > 0) {
                        jdbcTemplate.batchUpdate(insertSql, insertList);
                    }
                    if (updateList != null && updateList.size() > 0) {
                        jdbcTemplate.batchUpdate(updateSql, updateList);
                    }
                }

                return RestResultDto.success("同步材料结算数据成功");
            }
        }
        return RestResultDto.fail("没有结算记录信息");
    }
    /**计算主材费用**/
    private Map<String, MainMaterialBill> calcMaterial(JdbcTemplate jdbcTemplate, DataSourceInfo ds, SysReportTime reportTime,
                                       Map<Long, MainMaterial> materialMap, Map<Long, OaSupplier> supplierMap,
                                       List<MainMaterialWeightVo> weightList, SysOrigin org, String today,
                                       Long materialId, Long supplierId, Integer type, String creator, Integer isCloud) {
        List<MainMaterialContractPrice> materialPriceList = materialContractPriceDao.findWeightMaterialPrice(ds.getCode(), org.getId(), supplierId,
                materialId, 2, 1,reportTime.getStartTime(), reportTime.getEndTime(), MaterialContractTypeEnum.ZC.getCode());

        Date startDate = DateUtil.convertDate(reportTime.getStartTime());
        Date nowDate = new Date();
        Map<String, List<MainMaterialContractPrice>> mapPriceList = new HashMap<>();
        if (weightList != null && weightList.size() > 0) {
            for (int i = 0; i < materialPriceList.size(); i++) {
                MainMaterialContractPrice contractPrice = materialPriceList.get(i);
                String key = contractPrice.getSupplierId() + "_" + contractPrice.getMaterialId();
                if (mapPriceList.containsKey(key)) {
                    List<MainMaterialContractPrice> tempList = mapPriceList.get(key);
                    tempList.add(contractPrice);
                    mapPriceList.put(key, tempList);
                } else {
                    List<MainMaterialContractPrice> tempList = new ArrayList<>();
                    tempList.add(contractPrice);
                    mapPriceList.put(key, tempList);
                }
            }
        }
        Map<String, MainMaterialBill> billMap = new HashMap<>();//结算数据信息
        for (int i = 0; i < weightList.size(); i++) {
            MainMaterialWeightVo materialWeight = weightList.get(i);
            String key = materialWeight.getSupplierId() + "_" + materialWeight.getMaterialId();
            Date outTime = materialWeight.getOutTime();
            Double netWeight = materialWeight.getNetWeight();//净重
            Double supplierNetWeight = materialWeight.getSupplierNetWeight();//供方净重
            Long supplierId_ = materialWeight.getSupplierId();
            Long materialId_ = materialWeight.getMaterialId();
            Integer billWeightType = materialWeight.getBillWeightType();
            String supplier = "";
            String nameNorms = "";
            Double price = 0.0;
            String priceRemark = "";
            String remark = "";
            Date takeDate = materialWeight.getOutTime();
            String takeTime_ = DateUtil.convertString(materialWeight.getOutTime());
            if (supplierMap.get(supplierId_) != null)
                supplier = supplierMap.get(supplierId_).getFullName();
            if (materialMap.get(materialId_) != null)
                nameNorms = materialMap.get(materialId_).getNameNorms();
            Integer flag = 0;
            Integer isBill = BillEnum.JS.getCode();

            if (mapPriceList.containsKey(key)) {
                List<MainMaterialContractPrice> priceList = mapPriceList.get(key);
                if (priceList != null && priceList.size() > 0) {
                    for (int j = 0; j < priceList.size(); j++) {
                        MainMaterialContractPrice contractPrice = priceList.get(j);
                        Date takeTime = contractPrice.getTakeTime();
                        if (outTime.getTime() > takeTime.getTime()) {
                            if (!StringUtils.isNull(contractPrice.getIsBill()))
                                isBill = contractPrice.getIsBill();
                            takeTime_ = DateUtil.convertString(takeTime);
                            takeDate = takeTime;
                            price = contractPrice.getPrice();
                            remark = contractPrice.getRemark();
                            priceRemark = contractPrice.getPriceRemark();
                            if (!StringUtils.isNull(contractPrice.getBillWeightType()))
                                billWeightType = contractPrice.getBillWeightType();
                            flag = 1;
                            break;
                        }
                    }
                }
            }
            if (flag == 0) {
                price = 0.0;
                priceRemark = "未获取到价格信息";
            }
//                continue;
            if (flag == 1) {
                if (takeDate.getTime() < startDate.getTime()) {
                    priceRemark = "";
                }
            }

            key += "_" + takeTime_;
            if (billMap.containsKey(key)) {//累计材料过磅数据
                MainMaterialBill materialBill = billMap.get(key);
                materialBill.setBillWeightType(materialBill.getBillWeightType());
                materialBill.setWeight(materialBill.getWeight() + netWeight);
                materialBill.setSupplierWeight(materialBill.getSupplierWeight() + supplierNetWeight);
                billMap.put(key, materialBill);
            } else {
                MainMaterialBill materialBill = new MainMaterialBill(org.getId(), org.getOriginName(), supplierId_, supplier,
                        null, null, today, reportTime.getStartTime(), reportTime.getEndTime(), materialId_, nameNorms,
                        supplierNetWeight, netWeight, takeTime_, price, type, BillPriceTypeEnum.JS.getCode(), isBill,
                        CheckEnum.UHE.getCode(), "", null, CheckEnum.UHE.getCode(), "", null);
                materialBill.setBillWeightType(billWeightType);
                materialBill.setIsAuto(0);
                materialBill.setPriceRemark(priceRemark);
                materialBill.setStatus(0);
                materialBill.setRemark(remark);
                materialBill.setCreator(creator);
                materialBill.setCreateTime(nowDate);
                billMap.put(key, materialBill);
            }
        }
        return billMap;
    }

    /**
     * 获取供应商数据
     * @param orgId
     * @return
     */
    public List<Map<String,Object>> getSupplierList(Long orgId){
        return materialBillDao.getSupplierList(orgId);
    }

    /**
     * 获取材料数据
     * @param orgId
     * @return
     */
    public List<Map<String,Object>> getMaterialList(Long orgId){
        return materialBillDao.getMaterialList(orgId);
    }

    /**
     * 获取报表开始时间
     * @param
     * @return
     */
    public List<Map<String,Object>> getToDayList(){
        return materialBillDao.getToDayList();
    }


    /**
     * 审核方法
     * @param dto
     * @return
     */
    public RestResultDto auditdata(MainMaterialBillAuditDTO dto,CacheUser user){
        MainMaterialBill mainMaterialBill = detailByid(dto.getId());
        //材料审核
        if(dto.getType().equalsIgnoreCase("check")){
            if(mainMaterialBill.getIsCheck().intValue() != 0 || mainMaterialBill.getIsFinance().intValue() != 0){
                return RestResultDto.fail("当前数据已审核，请勿重复审核！");
            }
            mainMaterialBill.setIsCheck(1);
        }else{
            //财务审核
            if(mainMaterialBill.getIsCheck().intValue() != 1){
                return RestResultDto.fail("当前材料部门未审核，不允许审核！");
            }
            if(mainMaterialBill.getIsFinance().intValue() != 0){
                return RestResultDto.fail("当前数据已审核，请勿重复审核！");
            }
            mainMaterialBill.setIsFinance(1);
        }
        mainMaterialBill.setChecker(user.getName());
        mainMaterialBill.setCheckTime(new Date());
        return RestResultDto.success(materialBillDao.updateById(mainMaterialBill) > 0);
    }


    public MainMaterialBill detailByid(Long id){
        MainMaterialBill mainMaterialBill = materialBillDao.selectById(id);
        if(ObjectUtil.isEmpty(mainMaterialBill)){
            throw new IllegalArgumentException("当前数据不存在！");
        }
        return mainMaterialBill;
    }

    /**
     *
     * @param searchVal
     * @param today
     * @param startTime
     * @param endTime
     * @param type
     * @param status
     * @param supplierId
     * @param materialId
     * @param materialType
     * @return
     */
    protected QueryWrapper<MainMaterialBillVo> initFullParam(String searchVal, String today, String startTime,
        String endTime, Integer type, Integer status, Long supplierId, Long materialId, Long orgId,
        Integer materialType, Integer isBill) {
        QueryWrapper<MainMaterialBillVo> query = new QueryWrapper<>();
        if (StringUtils.isNull(status))
            status = 0;
        if (StringUtils.isNull(isBill))
            isBill = 0;
        query.eq("a.org_id", orgId);
        query.eq("a.status", status);
        if (!StringUtils.isNull(today))
            query.eq("a.today", today);
        if (!StringUtils.isNull(searchVal))
            query.and(orderWrapper -> orderWrapper.like("a.supplier", searchVal).or()
                    .like("a.material", searchVal).or().like("a.remark", searchVal)
                    .or().like("a.checker", searchVal).or().like("a.transport", searchVal)
                    .or().like("a.price_remark", searchVal));
        if (!StringUtils.isNull(startTime))
            query.ge("a.start_time", startTime);
        if (!StringUtils.isNull(endTime))
            query.lt("a.start_time", endTime);
        if (!StringUtils.isNull(type)) {
//            if (type != 4) {
//                Integer[] types = {MaterialContractTypeEnum.ZC.getCode(), MaterialContractTypeEnum.YSC.getCode(), MaterialContractTypeEnum.XS.getCode()};
//                query.in("a.type", types);
//            } else {
                query.eq("a.type", type);
//            }
        } else {
            Integer[] types = {MaterialContractTypeEnum.ZC.getCode(), MaterialContractTypeEnum.YSC.getCode(),
                    MaterialContractTypeEnum.YSS.getCode(), MaterialContractTypeEnum.JS.getCode(),
                    MaterialContractTypeEnum.XS.getCode()};
            query.in("a.type", types);
        }
        if (!StringUtils.isNull(supplierId))
            query.and(orderWrapper -> orderWrapper.eq("a.supplier_id", supplierId).or()
                    .eq("a.transport_id", supplierId));
        if (!StringUtils.isNull(materialId))
            query.eq("a.material_id", materialId);
        if (!StringUtils.isNull(isBill))
            query.eq("a.is_bill", isBill);
        if (!StringUtils.isNull(materialType))
            query.eq("b.type", materialType);

        query.orderByDesc("a.today");
        query.orderByAsc("b.type", "a.material_id", "a.supplier_id");
        query.orderByDesc("a.create_time");
        return query;
    }
}